{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "22746530",
   "metadata": {},
   "source": [
    "### R-group Analysis\n",
    "In this notebook, we will use an R-group decomposition to perform exploratory data analysis on a dataset from the ChEMBL database. We will define a common scaffold for a set of molecules and use the function [rdRGroupDecomposition.RGroupDecompose](https://www.rdkit.org/docs/source/rdkit.Chem.rdRGroupDecomposition.html) from the RDKit to create a table of substituents attached at different positions on the scaffold. To perform this analysis, we will carry out the following steps.\n",
    "\n",
    "- Read the input data from a SMILES file\n",
    "- Cluster the input data to identify similar molecules\n",
    "- View the largest cluster and identify the common scaffold\n",
    "- Perform the R-group decomposition\n",
    "- View the R-groups and their frequency\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b55a6007",
   "metadata": {},
   "source": [
    "#### Setup\n",
    "Install the necessary Python packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "9d006ee2",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-05T22:16:10.143027Z",
     "start_time": "2025-05-05T22:16:10.141525Z"
    }
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "IN_COLAB = 'google.colab' in sys.modules\n",
    "if IN_COLAB:\n",
    "    !pip install useful_rdkit_utils mols2grid"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6681d5fe",
   "metadata": {},
   "source": [
    "Import the necessary Python packages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "74fea3cd",
   "metadata": {},
   "outputs": [],
   "source": [
    "from rdkit import Chem\n",
    "from rdkit.Chem import rdRGroupDecomposition\n",
    "import pandas as pd\n",
    "import mols2grid\n",
    "import useful_rdkit_utils as uru\n",
    "from ipywidgets import interact"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6aa63401",
   "metadata": {},
   "source": [
    "#### Read the Input Data\n",
    "We begin by reading a set of molecules from a csv file.  The csv file has the SMILES, Name, and pIC50 for the molecules.  We'd like to find molecules with a common scaffold, then use that scaffold and decompose the molecules into R-groups around the common scaffold. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "74fa02a1",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv(\"https://raw.githubusercontent.com/PatWalters/practical_cheminformatics_tutorials/main/data/CHEMBL1075104.smi\",names=[\"SMILES\",\"Name\",\"pIC50\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "89e860f0",
   "metadata": {},
   "source": [
    "#### Cluster the Input Data to Identify Similar Molecules\n",
    "We'll begin by adding an RDKit molecule and a fingerprint to each molecule. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "c4049711",
   "metadata": {},
   "outputs": [],
   "source": [
    "df['mol'] = df.SMILES.apply(Chem.MolFromSmiles)\n",
    "df['fp'] = df.mol.apply(uru.mol2morgan_fp)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0dd4a21",
   "metadata": {},
   "source": [
    "In order to find molecules with a common scaffold, we'll cluster the molecules using the [Butina clustering](https://www.rdkit.org/docs/source/rdkit.ML.Cluster.Butina.html) method in the RDKit. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4f8dafa3",
   "metadata": {},
   "outputs": [],
   "source": [
    "df['cluster'] = uru.taylor_butina_clustering(df.fp.values)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33730037",
   "metadata": {},
   "source": [
    "Let's look at the sizes of the clusters. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "cc2f1fd7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0      73\n",
       "2      29\n",
       "1      26\n",
       "3      24\n",
       "7      14\n",
       "       ..\n",
       "212     1\n",
       "106     1\n",
       "213     1\n",
       "214     1\n",
       "110     1\n",
       "Name: cluster, Length: 310, dtype: int64"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.cluster.value_counts()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d7f55553",
   "metadata": {},
   "source": [
    "#### View the Largest Cluster and Identify the Common Scaffold\n",
    "Let's look at cluster 0, the largest cluster. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "4f7fade0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script>\n",
       "    function fit_height(obj) {\n",
       "        obj.style.height = 0;\n",
       "        var height = obj.contentDocument.body.scrollHeight + 18 + 'px';\n",
       "        obj.style.height = height;\n",
       "    }\n",
       "</script>\n",
       "<iframe class=\"mols2grid-iframe\" frameborder=\"0\" width=\"100%\"\n",
       "\n",
       "height=\"200\"\n",
       "\n",
       "\n",
       "allow=\"clipboard-write\"\n",
       "\n",
       "srcdoc=\"&lt;html&gt;\n",
       "  &lt;meta charset=&quot;utf-8&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;style&gt;\n",
       "    #mols2grid.gridcontainer {\n",
       "    display: block;\n",
       "    padding-left: 1em;\n",
       "    max-width: 820px;\n",
       "    width: 820px;\n",
       "}\n",
       "#mols2grid .cell {\n",
       "    border: 1px solid #cccccc;\n",
       "    text-align: center;\n",
       "    vertical-align: top;\n",
       "    max-width: 160px;\n",
       "    width: 160px;\n",
       "    font-family: &#x27;DejaVu&#x27;, sans-serif;\n",
       "    font-size: 12pt;\n",
       "    padding: 0;\n",
       "    margin: 0px;\n",
       "    float: left;\n",
       "}\n",
       "#mols2grid .cell:hover {\n",
       "    background-color: #e7e7e7 !important;\n",
       "}\n",
       "#mols2grid .cell .data-img {\n",
       "    padding: 0;\n",
       "    margin: 0;\n",
       "}\n",
       "#mols2grid .cell img, #mols2grid .cell svg {\n",
       "    max-width: 100%;\n",
       "    height: auto;\n",
       "    padding: 0;\n",
       "}\n",
       "#mols2grid .data {\n",
       "    overflow: hidden;\n",
       "    white-space: nowrap;\n",
       "    text-overflow: ellipsis;\n",
       "    display: block;\n",
       "}\n",
       "#mols2grid .arrow-asc:after {\n",
       "    content: &#x27;↑&#x27;;\n",
       "    text-align: right;\n",
       "    float:right;\n",
       "}\n",
       "#mols2grid .arrow-desc:after {\n",
       "    content: &#x27;↓&#x27;;\n",
       "    text-align: right;\n",
       "    float:right;\n",
       "}\n",
       "    /* custom CSS */\n",
       "    \n",
       "    &lt;/style&gt;\n",
       "    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/list.js/2.3.1/list.min.js&quot;&gt;&lt;/script&gt;\n",
       "&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css&quot; integrity=&quot;sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l&quot; crossorigin=&quot;anonymous&quot;&gt;\n",
       "&lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "&lt;script src=&quot;https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js&quot; integrity=&quot;sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "&lt;script src=&quot;https://unpkg.com/@rdkit/rdkit@2022.3.1/Code/MinimalLib/dist/RDKit_minimal.js&quot;&gt;&lt;/script&gt;\n",
       "    &lt;!-- custom header --&gt;\n",
       "    \n",
       "  &lt;/head&gt;\n",
       "  &lt;body&gt;\n",
       "    &lt;div id=&quot;mols2grid&quot; class=&quot;gridcontainer grid-default&quot;&gt;\n",
       "      &lt;div class=&quot;row mb-3&quot;&gt;\n",
       "        &lt;div class=&quot;list&quot;&gt;&lt;div class=&quot;cell&quot; data-mols2grid-id=&quot;0&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;position-relative float-left cached_checkbox&quot;&gt;&lt;div class=&quot;data data-img&quot;&gt;&lt;/div&gt;&lt;div class=&quot;data data-SMILES&quot; style=&quot;display: none;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;d-inline&quot;&gt;\n",
       "        &lt;ul class=&quot;pagination float-left&quot;&gt;&lt;/ul&gt;\n",
       "        &lt;div id=&quot;controls&quot; class=&quot;d-flex flex-row float-right&quot;&gt;\n",
       "          \n",
       "          &lt;div id=&quot;chkbox-dropdown&quot; class=&quot;dropdown&quot;&gt;\n",
       "    &lt;button class=&quot;btn btn-light dropdown-toggle&quot; type=&quot;button&quot; id=&quot;chkboxDropdown&quot; data-toggle=&quot;dropdown&quot; aria-haspopup=&quot;true&quot; aria-expanded=&quot;false&quot;&gt;☑&lt;/button&gt;\n",
       "    &lt;div class=&quot;dropdown-menu&quot; aria-labelledby=&quot;checkboxDropdownMenu&quot;&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-all&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Check all&lt;/button&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-match&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Check matching&lt;/button&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-none&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Uncheck all&lt;/button&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-invert&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Invert&lt;/button&gt;\n",
       "        &lt;div class=&quot;dropdown-divider&quot;&gt;&lt;/div&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-copy&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Copy to clipboard&lt;/button&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-dlsmi&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Save SMILES&lt;/button&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-dlcsv&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Save CSV&lt;/button&gt;\n",
       "    &lt;/div&gt;\n",
       "&lt;/div&gt;\n",
       "          \n",
       "          &lt;div id=&quot;sort-dropdown&quot; class=&quot;dropdown pl-2&quot;&gt;\n",
       "            &lt;button class=&quot;btn btn-light dropdown-toggle&quot; type=&quot;button&quot; id=&quot;sortDropdown&quot; data-toggle=&quot;dropdown&quot; aria-haspopup=&quot;true&quot; aria-expanded=&quot;false&quot;&gt;\n",
       "              Sort by\n",
       "            &lt;/button&gt;\n",
       "            &lt;div class=&quot;dropdown-menu&quot; aria-labelledby=&quot;sortDropdownMenu&quot;&gt;\n",
       "              \n",
       "              \n",
       "              \n",
       "              \n",
       "              \n",
       "              &lt;button class=&quot;dropdown-item sort-btn arrow-asc active&quot; type=&quot;button&quot; data-name=&quot;mols2grid-id&quot;&gt;Index&lt;/button&gt;\n",
       "              \n",
       "              \n",
       "              \n",
       "              &lt;button class=&quot;dropdown-item sort-btn&quot; type=&quot;button&quot; data-name=&quot;checkbox&quot;&gt;Selected&lt;/button&gt;\n",
       "              \n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "          &lt;div class=&quot;input-group row pl-4&quot;&gt;\n",
       "            &lt;input type=&quot;text&quot; id=&quot;searchbar&quot; class=&quot;form-control&quot; placeholder=&quot;Search&quot; aria-label=&quot;Search&quot; aria-describedby=&quot;basic-addon1&quot;&gt;\n",
       "            &lt;div class=&quot;input-group-append&quot;&gt;\n",
       "              &lt;button id=&quot;searchBtn&quot; class=&quot;btn btn-light dropdown-toggle&quot; type=&quot;button&quot; data-toggle=&quot;dropdown&quot; aria-haspopup=&quot;true&quot; aria-expanded=&quot;false&quot;&gt;🔎&lt;/button&gt;\n",
       "              &lt;div class=&quot;dropdown-menu dropdown-menu-right&quot;&gt;\n",
       "                &lt;button id=&quot;txtSearch&quot; class=&quot;search-btn dropdown-item active&quot;&gt;Text&lt;/button&gt;\n",
       "                &lt;button id=&quot;smartsSearch&quot; class=&quot;search-btn dropdown-item&quot;&gt;SMARTS&lt;/button&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    &lt;/div&gt;\n",
       "    &lt;script&gt;\n",
       "    // list.js\n",
       "var listObj = new List(&#x27;mols2grid&#x27;, {\n",
       "    valueNames: [{data: [&#x27;mols2grid-id&#x27;]}, &#x27;data-img&#x27;, &#x27;data-SMILES&#x27;],\n",
       "    item: &#x27;&lt;div class=&quot;cell&quot; data-mols2grid-id=&quot;0&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;position-relative float-left cached_checkbox&quot;&gt;&lt;div class=&quot;data data-img&quot;&gt;&lt;/div&gt;&lt;div class=&quot;data data-SMILES&quot; style=&quot;display: none;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&#x27;,\n",
       "    page: 15,\n",
       "    pagination: {\n",
       "        name: &quot;pagination&quot;,\n",
       "        item: &#x27;&lt;li class=&quot;page-item&quot;&gt;&lt;a class=&quot;page page-link&quot; href=&quot;#&quot; onclick=&quot;event.preventDefault()&quot;&gt;&lt;/a&gt;&lt;/li&gt;&#x27;,\n",
       "        innerWindow: 1,\n",
       "        outerWindow: 1,\n",
       "    },\n",
       "});\n",
       "listObj.remove(&quot;mols2grid-id&quot;, &quot;0&quot;);\n",
       "listObj.add([{&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 0, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 1, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC)ncc1C(F)(F)F&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 2, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC)ncc1F&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 3, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC)ncc1Br&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 4, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2Br)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 5, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2C)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 6, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 7, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Br)c(OC)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 8, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(OC)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 9, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N(C)C)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 10, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)NC3CC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 11, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC(F)F)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 12, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCN4CCCCC4C3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 13, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CC(C)CC(C)C3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 14, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCCCC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 15, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 16, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCC(F)(F)CC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 17, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCN(C(C)=O)CC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 18, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCCC(C(F)(F)F)C3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 19, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCCC3C)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 20, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCCC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 21, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCN(S(C)(=O)=O)CC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 22, &quot;data-SMILES&quot;: &quot;CCC1(CC)CN(C(=O)c2ccc(Nc3ncc(Cl)c(NC)n3)c(OC)c2)CCO1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 23, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3CO)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 24, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOC(CC(C)C)C3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 25, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCNCC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 26, &quot;data-SMILES&quot;: &quot;CCOc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(NC)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 27, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(N)=O)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 28, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)NC(C)C)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 29, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3C4CCC3COC4)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 30, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(OC(C)C)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 31, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CC4CC3CO4)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 32, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CC4CCC(C3)O4)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 33, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC)ncc1C1CC1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 34, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(NCC(C)C)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 35, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCN(C(=O)C4CC4)CC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 36, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC(C)C)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 37, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(NCC2CC2)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 38, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(NC2CCC2)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 39, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2O)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 40, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CC(N4CCOCC4)C3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 41, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(NC2(C)CCC2)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 42, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(NCC2CCOC2)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 43, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(I)c(OC)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 44, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(NCCC2CC2)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 45, &quot;data-SMILES&quot;: &quot;COCCNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 46, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2Cl)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 47, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC)ncc1OC&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 48, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2cc(OC)c(C(=O)N3CCCOCC3)cc2Cl)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 49, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(C2CC2)c(OC)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 50, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC)ncc1C(C)=O&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 51, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CC4(COC4)C3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 52, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2C2CC2)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 53, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(NC2CCOC2)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 54, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC2CC2)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 55, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC2CC2)ncc1Br&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 56, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(NCCS(C)(=O)=O)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 57, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2cc(OC)c(CC(=O)N3CCOCC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 58, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(CC(=O)N3CCOCC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 59, &quot;data-SMILES&quot;: &quot;COCCNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC)ncc1Br&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 60, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(NCC(C)OC)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 61, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(N2CCCCC2)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 62, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(N2CCCC2)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 63, &quot;data-SMILES&quot;: &quot;CCNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC)ncc1C(F)(F)F&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 64, &quot;data-SMILES&quot;: &quot;COc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2Cl)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 65, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(C(F)(F)F)c(OC)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 66, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(Cl)c(OC2CCOCC2)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 67, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2OC2COC2)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 68, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2Cl)ncc1C(F)(F)F&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 69, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2cc(Cl)c(C(=O)N3CCOCC3)cc2OC)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 70, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2cc(OC)c(C(=O)N3CCOCC3)cc2Cl)ncc1Cl&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 71, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCCC2)ccc1Nc1ncc(Cl)c(OC)n1&quot;}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 72, &quot;data-SMILES&quot;: &quot;COc1cc(C(=O)N2CCOCC2)ccc1Nc1ncc(C#N)c(OC)n1&quot;}]);\n",
       "// filter\n",
       "if (window.parent.mols2grid_lists === undefined) {\n",
       "    window.parent.mols2grid_lists = {};\n",
       "}\n",
       "window.parent.mols2grid_lists[&quot;default&quot;] = listObj;\n",
       "\n",
       "\n",
       "// selection\n",
       "class MolStorage extends Map {\n",
       "    multi_set(_id, _smiles) {\n",
       "        for (let i=0; i &lt; _id.length; i++) {\n",
       "            this.set(_id[i], _smiles[i]);\n",
       "        }\n",
       "    }\n",
       "    multi_del(_id) {\n",
       "        for (let i=0; i &lt; _id.length; i++) {\n",
       "            this.delete(_id[i]);\n",
       "        };\n",
       "    }\n",
       "    to_dict() {\n",
       "        var content = &quot;{&quot;;\n",
       "        for (let [key, value] of this) {\n",
       "            content += key + &quot;:&quot; + JSON.stringify(value) + &quot;,&quot;;\n",
       "        }\n",
       "        content = content.length &gt; 1 ? content.slice(0, -1) : content;\n",
       "        content += &quot;}&quot;;\n",
       "        return content\n",
       "    }\n",
       "    download_smi(fileName) {\n",
       "        var content = &quot;SMILES index\\n&quot;;\n",
       "        for (let [key, value] of this) {\n",
       "            content += value + &quot; &quot; + key + &quot;\\n&quot;;\n",
       "        }\n",
       "        var a = document.createElement(&quot;a&quot;);\n",
       "        var file = new Blob([content], {type: &quot;text/plain&quot;});\n",
       "        a.href = URL.createObjectURL(file);\n",
       "        a.download = fileName;\n",
       "        a.click();\n",
       "        a.remove();\n",
       "    }\n",
       "}\n",
       "var SELECTION = new MolStorage();\n",
       "\n",
       "\n",
       "\n",
       "// kernel\n",
       "var kernel_env = null;\n",
       "if (window.parent.IPython !== undefined) {\n",
       "    // Jupyter notebook\n",
       "    kernel_env = &quot;jupyter&quot;;\n",
       "    var kernel = window.parent.IPython.notebook.kernel;\n",
       "    kernel.execute(&#x27;from mols2grid.select import register as _m2g_reg&#x27;)\n",
       "    function add_selection(grid_id, _id, smiles) {\n",
       "        SELECTION.multi_set(_id, smiles);\n",
       "        kernel.execute(&quot;_m2g_reg.add_selection(&#x27;&quot;+grid_id+&quot;&#x27;, &quot;+JSON.stringify(_id)+&quot;,&quot;+JSON.stringify(smiles)+&quot;)&quot;);\n",
       "    }\n",
       "    function del_selection(grid_id, _id) {\n",
       "        SELECTION.multi_del(_id);\n",
       "        kernel.execute(&quot;_m2g_reg.del_selection(&#x27;&quot;+grid_id+&quot;&#x27;, &quot;+JSON.stringify(_id)+&quot;)&quot;);\n",
       "    }\n",
       "} else if (window.parent.google !== undefined) {\n",
       "    // Google colab\n",
       "    kernel_env = &quot;colab&quot;;\n",
       "    var kernel = window.parent.google.colab.kernel;\n",
       "    function add_selection(grid_id, _id, smiles) {\n",
       "        SELECTION.multi_set(_id, smiles);\n",
       "        (async function() {\n",
       "        const result = await kernel.invokeFunction(&#x27;_m2g_reg.add_selection&#x27;,\n",
       "                                                   [grid_id, _id, smiles], {});\n",
       "        })();\n",
       "    }\n",
       "    function del_selection(grid_id, _id) {\n",
       "        SELECTION.multi_del(_id);\n",
       "        (async function() {\n",
       "        const result = await kernel.invokeFunction(&#x27;_m2g_reg.del_selection&#x27;,\n",
       "                                                   [grid_id, _id], {});\n",
       "        })();\n",
       "    }\n",
       "} else {\n",
       "    function add_selection(grid_id, _id, smiles) {\n",
       "        SELECTION.multi_set(_id, smiles);\n",
       "    }\n",
       "    function del_selection(grid_id, _id) {\n",
       "        SELECTION.multi_del(_id);\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "// sort\n",
       "var sort_field = &quot;mols2grid-id&quot;;\n",
       "var sort_order = &quot;asc&quot;;\n",
       "function mols2gridSortFunction(itemA, itemB, options) {\n",
       "    var x = itemA.values()[options.valueName];\n",
       "    var y = itemB.values()[options.valueName];\n",
       "    if (typeof x === &quot;number&quot;) {\n",
       "        if (isFinite(x - y)) {\n",
       "            return x - y; \n",
       "        } else {\n",
       "            return isFinite(x) ? -1 : 1;\n",
       "        }\n",
       "    } else {\n",
       "        x = x.toLowerCase();\n",
       "        y = y.toLowerCase();\n",
       "        return (x &lt; y) ? -1: (x &gt; y) ? 1: 0;\n",
       "    }\n",
       "}\n",
       "function checkboxSort(itemA, itemB, options) {\n",
       "    if (itemA.elm !== undefined) {\n",
       "        var checkedA = itemA.elm.firstChild.checked;\n",
       "        if (itemB.elm !== undefined) {\n",
       "            var checkedB = itemB.elm.firstChild.checked;\n",
       "            if (checkedA &amp;&amp; !checkedB) {\n",
       "                return -1;\n",
       "            } else if (!checkedA &amp;&amp; checkedB) {\n",
       "                return 1;\n",
       "            } else {\n",
       "                return 0;\n",
       "            }\n",
       "        } else {\n",
       "            return -1;\n",
       "        }\n",
       "    } else if (itemB.elm !== undefined) {\n",
       "        return 1;\n",
       "    } else {\n",
       "        return 0;\n",
       "    }\n",
       "}\n",
       "$(&#x27;#mols2grid button.sort-btn&#x27;).click(function(e) {\n",
       "    var _field = $(this).attr(&quot;data-name&quot;);\n",
       "    if (_field == sort_field) {\n",
       "        $(this).removeClass(&quot;arrow-&quot; + sort_order)\n",
       "        sort_order = (sort_order === &quot;desc&quot;) ? &quot;asc&quot; : &quot;desc&quot;;\n",
       "    } else {\n",
       "        $(&#x27;#mols2grid button.sort-btn.active&#x27;).removeClass(&quot;active arrow-&quot; + sort_order);\n",
       "        sort_order = &quot;asc&quot;;\n",
       "        sort_field = _field;\n",
       "        $(this).addClass(&quot;active&quot;);\n",
       "    }\n",
       "    $(this).addClass(&quot;arrow-&quot; + sort_order)\n",
       "    if (sort_field == &quot;checkbox&quot;) {\n",
       "        listObj.sort(&quot;mols2grid-id&quot;, {order: sort_order, sortFunction: checkboxSort});\n",
       "    } else {\n",
       "        listObj.sort(_field, {order: sort_order, sortFunction: mols2gridSortFunction});\n",
       "    }\n",
       "});\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "// selection modifyers and export options\n",
       "// check all\n",
       "$(&#x27;#btn-chkbox-all&#x27;).click(function (e) {\n",
       "    var _id = [];\n",
       "    var _smiles = [];\n",
       "    listObj.items.forEach(function (item) {\n",
       "        if (item.elm) {\n",
       "            item.elm.getElementsByTagName(&quot;input&quot;)[0].checked = true;\n",
       "        } else {\n",
       "            item.show()\n",
       "            item.elm.getElementsByTagName(&quot;input&quot;)[0].checked = true;\n",
       "            item.hide()\n",
       "        }\n",
       "        _id.push(item.values()[&quot;mols2grid-id&quot;]);\n",
       "        _smiles.push(item.values()[&quot;data-SMILES&quot;]);\n",
       "    });\n",
       "    add_selection(&quot;default&quot;, _id, _smiles);\n",
       "});\n",
       "// check matching\n",
       "$(&#x27;#btn-chkbox-match&#x27;).click(function (e) {\n",
       "    var _id = [];\n",
       "    var _smiles = [];\n",
       "    listObj.matchingItems.forEach(function (item) {\n",
       "        if (item.elm) {\n",
       "            item.elm.getElementsByTagName(&quot;input&quot;)[0].checked = true;\n",
       "        } else {\n",
       "            item.show()\n",
       "            item.elm.getElementsByTagName(&quot;input&quot;)[0].checked = true;\n",
       "            item.hide()\n",
       "        }\n",
       "        _id.push(item.values()[&quot;mols2grid-id&quot;]);\n",
       "        _smiles.push(item.values()[&quot;data-SMILES&quot;]);\n",
       "    });\n",
       "    add_selection(&quot;default&quot;, _id, _smiles);\n",
       "});\n",
       "// uncheck all\n",
       "$(&#x27;#btn-chkbox-none&#x27;).click(function (e) {\n",
       "    var _id = [];\n",
       "    listObj.items.forEach(function (item) {\n",
       "        if (item.elm) {\n",
       "            item.elm.getElementsByTagName(&quot;input&quot;)[0].checked = false;\n",
       "        } else {\n",
       "            item.show()\n",
       "            item.elm.getElementsByTagName(&quot;input&quot;)[0].checked = false;\n",
       "            item.hide()\n",
       "        }\n",
       "        _id.push(item.values()[&quot;mols2grid-id&quot;]);\n",
       "    });\n",
       "    del_selection(&quot;default&quot;, _id);\n",
       "});\n",
       "// invert\n",
       "$(&#x27;#btn-chkbox-invert&#x27;).click(function (e) {\n",
       "    var _id_add = [];\n",
       "    var _id_del = [];\n",
       "    var _smiles = [];\n",
       "    listObj.items.forEach(function (item) {\n",
       "        if (item.elm) {\n",
       "            var chkbox = item.elm.getElementsByTagName(&quot;input&quot;)[0]\n",
       "            chkbox.checked = !chkbox.checked;\n",
       "        } else {\n",
       "            item.show()\n",
       "            var chkbox = item.elm.getElementsByTagName(&quot;input&quot;)[0]\n",
       "            chkbox.checked = !chkbox.checked;\n",
       "            item.hide()\n",
       "        }\n",
       "        if (chkbox.checked) {\n",
       "            _id_add.push(item.values()[&quot;mols2grid-id&quot;]);\n",
       "            _smiles.push(item.values()[&quot;data-SMILES&quot;]);\n",
       "        } else {\n",
       "            _id_del.push(item.values()[&quot;mols2grid-id&quot;]);\n",
       "        }\n",
       "    });\n",
       "    del_selection(&quot;default&quot;, _id_del);\n",
       "    add_selection(&quot;default&quot;, _id_add, _smiles);\n",
       "});\n",
       "// copy to clipboard\n",
       "$(&quot;#btn-chkbox-copy&quot;).click(function(e) {\n",
       "    navigator.clipboard.writeText(SELECTION.to_dict());\n",
       "});\n",
       "// export smiles\n",
       "$(&quot;#btn-chkbox-dlsmi&quot;).click(function(e) {\n",
       "    SELECTION.download_smi(&quot;selection.smi&quot;);\n",
       "});\n",
       "// export CSV\n",
       "$(&quot;#btn-chkbox-dlcsv&quot;).click(function(e) {\n",
       "    var sep = &quot;\\t&quot;\n",
       "    // same order as subset + tooltip\n",
       "    var columns = Array.from(listObj.items[0].elm.querySelectorAll(&quot;div.data&quot;))\n",
       "                       .map(elm =&gt; elm.classList[1]);\n",
       "    // remove &#x27;data-&#x27;\n",
       "    var header = columns.map(name =&gt; name.slice(5));\n",
       "    // csv content\n",
       "    header = [&quot;index&quot;].concat(header).join(sep);\n",
       "    var content = header + &quot;\\n&quot;;\n",
       "    for (let [index, smiles] of SELECTION.entries()) {\n",
       "        var data = listObj.items[index].values();\n",
       "        content += index;\n",
       "        columns.forEach((key) =&gt; {\n",
       "            content += sep + data[key];\n",
       "        })\n",
       "        content += &quot;\\n&quot;;\n",
       "    }\n",
       "    var a = document.createElement(&quot;a&quot;);\n",
       "    var file = new Blob([content], {type: &quot;text/csv&quot;});\n",
       "    a.href = URL.createObjectURL(file);\n",
       "    a.download = &quot;selection.csv&quot;;\n",
       "    a.click();\n",
       "    a.remove();\n",
       "});\n",
       "// update selection on checkbox click\n",
       "listObj.on(&quot;updated&quot;, function (list) {\n",
       "    $(&quot;input:checkbox&quot;).change(function() {\n",
       "        var _id = parseInt($(this).closest(&quot;.cell&quot;).attr(&quot;data-mols2grid-id&quot;));\n",
       "        if (this.checked) {\n",
       "            var _smiles = $($(this).siblings(&quot;.data-SMILES&quot;)[0]).text();\n",
       "            add_selection(&quot;default&quot;, [_id], [_smiles]);\n",
       "        } else {\n",
       "            del_selection(&quot;default&quot;, [_id]);\n",
       "        }\n",
       "    }); \n",
       "});\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "// generate images for the currently displayed molecules\n",
       "var draw_opts = {&quot;width&quot;: 160, &quot;height&quot;: 120};\n",
       "var json_draw_opts = JSON.stringify(draw_opts);\n",
       "\n",
       "var smarts_matches = {};\n",
       "\n",
       "// Load RDKit\n",
       "window\n",
       ".initRDKitModule()\n",
       ".then(function(RDKit) {\n",
       "    console.log(&#x27;RDKit version: &#x27;, RDKit.version());\n",
       "    window.RDKit = RDKit;\n",
       "    window.RDKitModule = RDKit;\n",
       "\n",
       "    // search bar\n",
       "    function SmartsSearch(query, columns) {\n",
       "    var smiles_col = columns[0];\n",
       "    smarts_matches = {};\n",
       "    var query = $(&#x27;#mols2grid #searchbar&#x27;).val();\n",
       "    var qmol = RDKit.get_qmol(query);\n",
       "    if (qmol.is_valid()) {\n",
       "        listObj.items.forEach(function (item) {\n",
       "            var smiles = item.values()[smiles_col]\n",
       "            var mol = RDKit.get_mol(smiles);\n",
       "            if (mol.is_valid()) {\n",
       "                var results = mol.get_substruct_matches(qmol);\n",
       "                if (results === &quot;\\{\\}&quot;) {\n",
       "                    item.found = false;\n",
       "                } else {\n",
       "                    item.found = true;\n",
       "                    \n",
       "                    results = JSON.parse(results);\n",
       "                    \n",
       "                    var highlights = {&quot;atoms&quot;: [], &quot;bonds&quot;: []};\n",
       "                    results.forEach(function (match) {\n",
       "                        highlights[&quot;atoms&quot;].push(...match.atoms)\n",
       "                        highlights[&quot;bonds&quot;].push(...match.bonds)\n",
       "                    });\n",
       "                    \n",
       "                    var index = item.values()[&quot;mols2grid-id&quot;];\n",
       "                    smarts_matches[index] = highlights;\n",
       "                    \n",
       "                }\n",
       "            } else {\n",
       "                item.found = false;\n",
       "            }\n",
       "            mol.delete();\n",
       "        });\n",
       "    }\n",
       "    qmol.delete();\n",
       "}\n",
       "var search_type = &quot;Text&quot;;\n",
       "$(&#x27;#mols2grid .search-btn&#x27;).click(function() {\n",
       "    search_type = $(this).text();\n",
       "    $(&#x27;#mols2grid button.search-btn.active&#x27;).removeClass(&quot;active&quot;);\n",
       "    $(this).addClass(&quot;active&quot;);\n",
       "});\n",
       "$(&#x27;#mols2grid #searchbar&#x27;).on(&quot;keyup&quot;, function(e) {\n",
       "    var query = e.target.value;\n",
       "    if (search_type === &quot;Text&quot;) {\n",
       "        smarts_matches = {};\n",
       "        listObj.search(query, []);\n",
       "    } else {\n",
       "        listObj.search(query, [&quot;data-SMILES&quot;], SmartsSearch);\n",
       "    }\n",
       "});\n",
       "\n",
       "    \n",
       "    // generate images for the currently displayed molecules\n",
       "RDKit.prefer_coordgen(true);\n",
       "function draw_mol(smiles, index, template_mol) {\n",
       "    var mol = RDKit.get_mol(smiles, &#x27;{&quot;removeHs&quot;: false }&#x27;);\n",
       "    var svg = &quot;&quot;;\n",
       "    if (mol.is_valid()) {\n",
       "        var highlights = smarts_matches[index];\n",
       "        if (highlights) {\n",
       "            var details = Object.assign({}, draw_opts, highlights);\n",
       "            details = JSON.stringify(details);\n",
       "            mol.generate_aligned_coords(template_mol, true);\n",
       "        } else {\n",
       "            var details = json_draw_opts;\n",
       "        }\n",
       "        svg = mol.get_svg_with_highlights(details);\n",
       "    }\n",
       "    mol.delete();\n",
       "    if (svg == &quot;&quot;) {\n",
       "        return &#x27;&lt;svg width=&quot;160&quot; height=&quot;120&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 160 120&quot;&gt;&lt;/svg&gt;&#x27;;\n",
       "    }\n",
       "    return svg;\n",
       "}\n",
       "listObj.on(&quot;updated&quot;, function (list) {\n",
       "    var query = $(&#x27;#mols2grid #searchbar&#x27;).val();\n",
       "    var template_mol;\n",
       "    if (query === &quot;&quot;) {\n",
       "        smarts_matches = {};\n",
       "        template_mol = null;\n",
       "    } else {\n",
       "        template_mol = RDKit.get_qmol(query);\n",
       "        template_mol.set_new_coords(true);\n",
       "    }\n",
       "    $(&#x27;#mols2grid .cell&#x27;).each(function() {\n",
       "        var $t = $(this);\n",
       "        var smiles = $t.children(&quot;.data-SMILES&quot;).first().text();\n",
       "        var index = parseInt(this.getAttribute(&quot;data-mols2grid-id&quot;));\n",
       "        var svg = draw_mol(smiles, index, template_mol);\n",
       "        $t.children(&quot;.data-img&quot;).html(svg);\n",
       "    });\n",
       "    if (template_mol) {\n",
       "        template_mol.delete();\n",
       "    }\n",
       "});\n",
       "    \n",
       "\n",
       "    // trigger update to activate tooltips, draw images, setup callbacks...\n",
       "    listObj.update();\n",
       "    // resize iframe to fit content\n",
       "    if (window.frameElement) {\n",
       "        window.parent.fit_height(window.frameElement);\n",
       "    }\n",
       "});\n",
       "    &lt;/script&gt;\n",
       "  &lt;/body&gt;\n",
       "&lt;/html&gt;\">\n",
       "</iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mols2grid.display(df.query(\"cluster == 0\"),mol_col=\"mol\",subset=[\"img\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c733b4f3",
   "metadata": {},
   "source": [
    "At first glance, it looks like the structure below is the scaffold.  Try searching the structures with that scaffold. \n",
    "- Click on the arrow next to the magnifying glass in the grid above and select **SMARTS**. \n",
    "- Paste the SMILES from the box below into the **Search** box. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "cd6ccb82",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<rdkit.Chem.rdchem.Mol at 0x12696a2e0>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Chem.MolFromSmiles(\"[*]C(=O)c1ccc(N[*])c(O[*])c1\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59e25b38",
   "metadata": {},
   "source": [
    "We can sketch the scaffold with R-groups in place and save the core with R-groups to a molfile. I sketched this with [Marvin Sketch](https://marvinjs-demo.chemaxon.com/latest/examples/demo.html) but you should be able to use any chemical sketcher. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "81531c53",
   "metadata": {},
   "outputs": [],
   "source": [
    "mb = \"\"\"\n",
    "  Mrv2004 04242220562D          \n",
    "\n",
    " 13 13  0  0  0  0            999 V2000\n",
    "   -1.0632    2.0028    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
    "   -1.7777    1.5903    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
    "   -1.7777    0.7652    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
    "   -1.0632    0.3527    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
    "   -0.3488    0.7652    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
    "   -0.3488    1.5903    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
    "    0.3321    1.9834    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0\n",
    "   -2.4922    2.0028    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n",
    "   -2.4922    2.8278    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0\n",
    "    0.3057    0.2630    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0\n",
    "   -3.2067    1.5903    0.0000 R#  0  0  0  0  0  0  0  0  0  0  0  0\n",
    "    1.0466    1.5709    0.0000 R#  0  0  0  0  0  0  0  0  0  0  0  0\n",
    "    0.3057   -0.5620    0.0000 R#  0  0  0  0  0  0  0  0  0  0  0  0\n",
    "  1  2  2  0  0  0  0\n",
    "  2  3  1  0  0  0  0\n",
    "  3  4  2  0  0  0  0\n",
    "  4  5  1  0  0  0  0\n",
    "  5  6  2  0  0  0  0\n",
    "  1  6  1  0  0  0  0\n",
    "  6  7  1  0  0  0  0\n",
    "  2  8  1  0  0  0  0\n",
    "  8  9  2  0  0  0  0\n",
    "  5 10  1  0  0  0  0\n",
    "  8 11  1  0  0  0  0\n",
    "  7 12  1  0  0  0  0\n",
    " 10 13  1  0  0  0  0\n",
    "M  RGP  3  11   1  12   2  13   3\n",
    "M  END\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5287fdd8",
   "metadata": {},
   "source": [
    "We can then convert the molfile to an RDKit molecule. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "b5b21b60",
   "metadata": {},
   "outputs": [],
   "source": [
    "core = Chem.MolFromMolBlock(mb)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "612380d1",
   "metadata": {},
   "source": [
    "Here's the core molecule. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "d7d17f61",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<rdkit.Chem.rdchem.Mol at 0x12711f3a0>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "core"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0ad2f45",
   "metadata": {},
   "source": [
    "Now let's create a new Pandas dataframe from the molecules in cluster 0. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "002287d6",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_0 = df.query(\"cluster == 0\").copy()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4bd16f01",
   "metadata": {},
   "source": [
    "We'll add an index column to keep track of things"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "cc26fd4e",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_0['index'] = range(0,len(df_0))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "995407cc",
   "metadata": {},
   "source": [
    "### Perform the R-group Decomposition\n",
    "As mentioned above, we're using the function [rdRGroupDecomposition.RGroupDecompose](https://www.rdkit.org/docs/source/rdkit.Chem.rdRGroupDecomposition.html) from the RDKit. Note that RDKit returns two values from this function.  \n",
    "\n",
    "- rgd - a dictionary containing the results of the R-group decomposition. This dictionary has keys containing the core with a key \"Core\", and the R-groups in keys named \"R1\", \"R2\", etc. Each dictionary key links to a list of cores or R-groups corresponding input molecules that matched the core (didn't fail).\n",
    "- failed - a list containing the indices of molecules that did not match the core.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "9dda5575",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "RDKit DEBUG: [11:45:20] No core matches\n",
      "[11:45:20] No core matches\n",
      "[11:45:20] No core matches\n",
      "RDKit DEBUG: [11:45:20] No core matches\n",
      "RDKit DEBUG: [11:45:20] No core matches\n",
      "[11:45:20] No core matches\n",
      "RDKit DEBUG: [11:45:20] No core matches\n",
      "[11:45:20] No core matches\n",
      "RDKit DEBUG: [11:45:20] No core matches\n",
      "[11:45:20] No core matches\n",
      "RDKit DEBUG: [11:45:20] No core matches\n",
      "[11:45:20] No core matches\n",
      "RDKit DEBUG: [11:45:20] No core matches\n",
      "[11:45:20] No core matches\n",
      "RDKit DEBUG: [11:45:20] No core matches\n",
      "[11:45:20] No core matches\n",
      "RDKit DEBUG: [11:45:20] No core matches\n",
      "[11:45:20] No core matches\n",
      "RDKit DEBUG: [11:45:20] No core matches\n",
      "[11:45:20] No core matches\n",
      "RDKit DEBUG: [11:45:20] No core matches\n",
      "[11:45:20] No core matches\n"
     ]
    }
   ],
   "source": [
    "rgd,failed = rdRGroupDecomposition.RGroupDecompose([core],df_0.mol.values,asRows=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb409e1a",
   "metadata": {},
   "source": [
    "Let's look at the first core, all the rest should be the same. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "c2db9515",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<rdkit.Chem.rdchem.Mol at 0x12699c7b0>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rgd['Core'][0]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e55e14f",
   "metadata": {},
   "source": [
    "Note this core has 4 R-groups, while our input core has 3.  Scroll up and see for yourself.  This is very cool!  The RDKit noticed another point of substitution and added an R-group for us. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "17e7b52a",
   "metadata": {},
   "source": [
    "Here are the indices of the molecules that failed. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "4f0b3c02",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[4, 5, 6, 46, 48, 52, 57, 58, 64, 68, 70]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "failed"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1ea1aa86",
   "metadata": {},
   "source": [
    "Let's look at the molecules that failed and try to figure out why. These results make sense.  \n",
    "- Molecule 4 has a **Br** in place of the **O** in the core\n",
    "- Molecule 5 has a **methyl** in place of the oxygen in the core\n",
    "- Molecule 6 does not have an **O** connected to the core\n",
    "- etc\n",
    "\n",
    "In some cases, we may want to go back and modify our core definition to include these molecules.  In this case, we'll just skip them."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "ac015a36",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script>\n",
       "    function fit_height(obj) {\n",
       "        obj.style.height = 0;\n",
       "        var height = obj.contentDocument.body.scrollHeight + 18 + 'px';\n",
       "        obj.style.height = height;\n",
       "    }\n",
       "</script>\n",
       "<iframe class=\"mols2grid-iframe\" frameborder=\"0\" width=\"100%\"\n",
       "\n",
       "height=\"200\"\n",
       "\n",
       "\n",
       "allow=\"clipboard-write\"\n",
       "\n",
       "srcdoc=\"&lt;html&gt;\n",
       "  &lt;meta charset=&quot;utf-8&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;style&gt;\n",
       "    #mols2grid.gridcontainer {\n",
       "    display: block;\n",
       "    padding-left: 1em;\n",
       "    max-width: 820px;\n",
       "    width: 820px;\n",
       "}\n",
       "#mols2grid .cell {\n",
       "    border: 1px solid #cccccc;\n",
       "    text-align: center;\n",
       "    vertical-align: top;\n",
       "    max-width: 160px;\n",
       "    width: 160px;\n",
       "    font-family: &#x27;DejaVu&#x27;, sans-serif;\n",
       "    font-size: 12pt;\n",
       "    padding: 0;\n",
       "    margin: 0px;\n",
       "    float: left;\n",
       "}\n",
       "#mols2grid .cell:hover {\n",
       "    background-color: #e7e7e7 !important;\n",
       "}\n",
       "#mols2grid .cell .data-img {\n",
       "    padding: 0;\n",
       "    margin: 0;\n",
       "}\n",
       "#mols2grid .cell img, #mols2grid .cell svg {\n",
       "    max-width: 100%;\n",
       "    height: auto;\n",
       "    padding: 0;\n",
       "}\n",
       "#mols2grid .data {\n",
       "    overflow: hidden;\n",
       "    white-space: nowrap;\n",
       "    text-overflow: ellipsis;\n",
       "    display: block;\n",
       "}\n",
       "#mols2grid .arrow-asc:after {\n",
       "    content: &#x27;↑&#x27;;\n",
       "    text-align: right;\n",
       "    float:right;\n",
       "}\n",
       "#mols2grid .arrow-desc:after {\n",
       "    content: &#x27;↓&#x27;;\n",
       "    text-align: right;\n",
       "    float:right;\n",
       "}\n",
       "    /* custom CSS */\n",
       "    \n",
       "    &lt;/style&gt;\n",
       "    &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/list.js/2.3.1/list.min.js&quot;&gt;&lt;/script&gt;\n",
       "&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css&quot; integrity=&quot;sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l&quot; crossorigin=&quot;anonymous&quot;&gt;\n",
       "&lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "&lt;script src=&quot;https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js&quot; integrity=&quot;sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "&lt;script src=&quot;https://unpkg.com/@rdkit/rdkit@2022.3.1/Code/MinimalLib/dist/RDKit_minimal.js&quot;&gt;&lt;/script&gt;\n",
       "    &lt;!-- custom header --&gt;\n",
       "    \n",
       "  &lt;/head&gt;\n",
       "  &lt;body&gt;\n",
       "    &lt;div id=&quot;mols2grid&quot; class=&quot;gridcontainer grid-default&quot;&gt;\n",
       "      &lt;div class=&quot;row mb-3&quot;&gt;\n",
       "        &lt;div class=&quot;list&quot;&gt;&lt;div class=&quot;cell&quot; data-mols2grid-id=&quot;0&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;position-relative float-left cached_checkbox&quot;&gt;&lt;div class=&quot;data data-img&quot;&gt;&lt;/div&gt;&lt;div class=&quot;data data-index&quot;&gt;&lt;/div&gt;&lt;div class=&quot;data data-SMILES&quot; style=&quot;display: none;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;d-inline&quot;&gt;\n",
       "        &lt;ul class=&quot;pagination float-left&quot;&gt;&lt;/ul&gt;\n",
       "        &lt;div id=&quot;controls&quot; class=&quot;d-flex flex-row float-right&quot;&gt;\n",
       "          \n",
       "          &lt;div id=&quot;chkbox-dropdown&quot; class=&quot;dropdown&quot;&gt;\n",
       "    &lt;button class=&quot;btn btn-light dropdown-toggle&quot; type=&quot;button&quot; id=&quot;chkboxDropdown&quot; data-toggle=&quot;dropdown&quot; aria-haspopup=&quot;true&quot; aria-expanded=&quot;false&quot;&gt;☑&lt;/button&gt;\n",
       "    &lt;div class=&quot;dropdown-menu&quot; aria-labelledby=&quot;checkboxDropdownMenu&quot;&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-all&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Check all&lt;/button&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-match&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Check matching&lt;/button&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-none&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Uncheck all&lt;/button&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-invert&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Invert&lt;/button&gt;\n",
       "        &lt;div class=&quot;dropdown-divider&quot;&gt;&lt;/div&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-copy&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Copy to clipboard&lt;/button&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-dlsmi&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Save SMILES&lt;/button&gt;\n",
       "        &lt;button id=&quot;btn-chkbox-dlcsv&quot; class=&quot;dropdown-item&quot; type=&quot;button&quot;&gt;Save CSV&lt;/button&gt;\n",
       "    &lt;/div&gt;\n",
       "&lt;/div&gt;\n",
       "          \n",
       "          &lt;div id=&quot;sort-dropdown&quot; class=&quot;dropdown pl-2&quot;&gt;\n",
       "            &lt;button class=&quot;btn btn-light dropdown-toggle&quot; type=&quot;button&quot; id=&quot;sortDropdown&quot; data-toggle=&quot;dropdown&quot; aria-haspopup=&quot;true&quot; aria-expanded=&quot;false&quot;&gt;\n",
       "              Sort by\n",
       "            &lt;/button&gt;\n",
       "            &lt;div class=&quot;dropdown-menu&quot; aria-labelledby=&quot;sortDropdownMenu&quot;&gt;\n",
       "              \n",
       "              \n",
       "              \n",
       "              \n",
       "              \n",
       "              &lt;button class=&quot;dropdown-item sort-btn arrow-asc active&quot; type=&quot;button&quot; data-name=&quot;mols2grid-id&quot;&gt;Index&lt;/button&gt;\n",
       "              \n",
       "              \n",
       "              \n",
       "              \n",
       "              \n",
       "              &lt;button class=&quot;dropdown-item sort-btn &quot; type=&quot;button&quot; data-name=&quot;data-index&quot;&gt;index&lt;/button&gt;\n",
       "              \n",
       "              \n",
       "              \n",
       "              &lt;button class=&quot;dropdown-item sort-btn&quot; type=&quot;button&quot; data-name=&quot;checkbox&quot;&gt;Selected&lt;/button&gt;\n",
       "              \n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "          &lt;div class=&quot;input-group row pl-4&quot;&gt;\n",
       "            &lt;input type=&quot;text&quot; id=&quot;searchbar&quot; class=&quot;form-control&quot; placeholder=&quot;Search&quot; aria-label=&quot;Search&quot; aria-describedby=&quot;basic-addon1&quot;&gt;\n",
       "            &lt;div class=&quot;input-group-append&quot;&gt;\n",
       "              &lt;button id=&quot;searchBtn&quot; class=&quot;btn btn-light dropdown-toggle&quot; type=&quot;button&quot; data-toggle=&quot;dropdown&quot; aria-haspopup=&quot;true&quot; aria-expanded=&quot;false&quot;&gt;🔎&lt;/button&gt;\n",
       "              &lt;div class=&quot;dropdown-menu dropdown-menu-right&quot;&gt;\n",
       "                &lt;button id=&quot;txtSearch&quot; class=&quot;search-btn dropdown-item active&quot;&gt;Text&lt;/button&gt;\n",
       "                &lt;button id=&quot;smartsSearch&quot; class=&quot;search-btn dropdown-item&quot;&gt;SMARTS&lt;/button&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    &lt;/div&gt;\n",
       "    &lt;script&gt;\n",
       "    // list.js\n",
       "var listObj = new List(&#x27;mols2grid&#x27;, {\n",
       "    valueNames: [{data: [&#x27;mols2grid-id&#x27;]}, &#x27;data-img&#x27;, &#x27;data-SMILES&#x27;, &#x27;data-index&#x27;],\n",
       "    item: &#x27;&lt;div class=&quot;cell&quot; data-mols2grid-id=&quot;0&quot;&gt;&lt;input type=&quot;checkbox&quot; class=&quot;position-relative float-left cached_checkbox&quot;&gt;&lt;div class=&quot;data data-img&quot;&gt;&lt;/div&gt;&lt;div class=&quot;data data-index&quot;&gt;&lt;/div&gt;&lt;div class=&quot;data data-SMILES&quot; style=&quot;display: none;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&#x27;,\n",
       "    page: 15,\n",
       "    pagination: {\n",
       "        name: &quot;pagination&quot;,\n",
       "        item: &#x27;&lt;li class=&quot;page-item&quot;&gt;&lt;a class=&quot;page page-link&quot; href=&quot;#&quot; onclick=&quot;event.preventDefault()&quot;&gt;&lt;/a&gt;&lt;/li&gt;&#x27;,\n",
       "        innerWindow: 1,\n",
       "        outerWindow: 1,\n",
       "    },\n",
       "});\n",
       "listObj.remove(&quot;mols2grid-id&quot;, &quot;0&quot;);\n",
       "listObj.add([{&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 0, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2Br)ncc1Cl&quot;, &quot;data-index&quot;: 4}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 1, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2C)ncc1Cl&quot;, &quot;data-index&quot;: 5}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 2, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2)ncc1Cl&quot;, &quot;data-index&quot;: 6}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 3, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2Cl)ncc1Cl&quot;, &quot;data-index&quot;: 46}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 4, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2cc(OC)c(C(=O)N3CCCOCC3)cc2Cl)ncc1Cl&quot;, &quot;data-index&quot;: 48}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 5, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2C2CC2)ncc1Cl&quot;, &quot;data-index&quot;: 52}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 6, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2cc(OC)c(CC(=O)N3CCOCC3)cc2OC)ncc1Cl&quot;, &quot;data-index&quot;: 57}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 7, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(CC(=O)N3CCOCC3)cc2OC)ncc1Cl&quot;, &quot;data-index&quot;: 58}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 8, &quot;data-SMILES&quot;: &quot;COc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2Cl)ncc1Cl&quot;, &quot;data-index&quot;: 64}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 9, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2ccc(C(=O)N3CCOCC3)cc2Cl)ncc1C(F)(F)F&quot;, &quot;data-index&quot;: 68}, {&quot;data-img&quot;: null, &quot;mols2grid-id&quot;: 10, &quot;data-SMILES&quot;: &quot;CNc1nc(Nc2cc(OC)c(C(=O)N3CCOCC3)cc2Cl)ncc1Cl&quot;, &quot;data-index&quot;: 70}]);\n",
       "// filter\n",
       "if (window.parent.mols2grid_lists === undefined) {\n",
       "    window.parent.mols2grid_lists = {};\n",
       "}\n",
       "window.parent.mols2grid_lists[&quot;default&quot;] = listObj;\n",
       "\n",
       "\n",
       "// selection\n",
       "class MolStorage extends Map {\n",
       "    multi_set(_id, _smiles) {\n",
       "        for (let i=0; i &lt; _id.length; i++) {\n",
       "            this.set(_id[i], _smiles[i]);\n",
       "        }\n",
       "    }\n",
       "    multi_del(_id) {\n",
       "        for (let i=0; i &lt; _id.length; i++) {\n",
       "            this.delete(_id[i]);\n",
       "        };\n",
       "    }\n",
       "    to_dict() {\n",
       "        var content = &quot;{&quot;;\n",
       "        for (let [key, value] of this) {\n",
       "            content += key + &quot;:&quot; + JSON.stringify(value) + &quot;,&quot;;\n",
       "        }\n",
       "        content = content.length &gt; 1 ? content.slice(0, -1) : content;\n",
       "        content += &quot;}&quot;;\n",
       "        return content\n",
       "    }\n",
       "    download_smi(fileName) {\n",
       "        var content = &quot;SMILES index\\n&quot;;\n",
       "        for (let [key, value] of this) {\n",
       "            content += value + &quot; &quot; + key + &quot;\\n&quot;;\n",
       "        }\n",
       "        var a = document.createElement(&quot;a&quot;);\n",
       "        var file = new Blob([content], {type: &quot;text/plain&quot;});\n",
       "        a.href = URL.createObjectURL(file);\n",
       "        a.download = fileName;\n",
       "        a.click();\n",
       "        a.remove();\n",
       "    }\n",
       "}\n",
       "var SELECTION = new MolStorage();\n",
       "\n",
       "\n",
       "\n",
       "// kernel\n",
       "var kernel_env = null;\n",
       "if (window.parent.IPython !== undefined) {\n",
       "    // Jupyter notebook\n",
       "    kernel_env = &quot;jupyter&quot;;\n",
       "    var kernel = window.parent.IPython.notebook.kernel;\n",
       "    kernel.execute(&#x27;from mols2grid.select import register as _m2g_reg&#x27;)\n",
       "    function add_selection(grid_id, _id, smiles) {\n",
       "        SELECTION.multi_set(_id, smiles);\n",
       "        kernel.execute(&quot;_m2g_reg.add_selection(&#x27;&quot;+grid_id+&quot;&#x27;, &quot;+JSON.stringify(_id)+&quot;,&quot;+JSON.stringify(smiles)+&quot;)&quot;);\n",
       "    }\n",
       "    function del_selection(grid_id, _id) {\n",
       "        SELECTION.multi_del(_id);\n",
       "        kernel.execute(&quot;_m2g_reg.del_selection(&#x27;&quot;+grid_id+&quot;&#x27;, &quot;+JSON.stringify(_id)+&quot;)&quot;);\n",
       "    }\n",
       "} else if (window.parent.google !== undefined) {\n",
       "    // Google colab\n",
       "    kernel_env = &quot;colab&quot;;\n",
       "    var kernel = window.parent.google.colab.kernel;\n",
       "    function add_selection(grid_id, _id, smiles) {\n",
       "        SELECTION.multi_set(_id, smiles);\n",
       "        (async function() {\n",
       "        const result = await kernel.invokeFunction(&#x27;_m2g_reg.add_selection&#x27;,\n",
       "                                                   [grid_id, _id, smiles], {});\n",
       "        })();\n",
       "    }\n",
       "    function del_selection(grid_id, _id) {\n",
       "        SELECTION.multi_del(_id);\n",
       "        (async function() {\n",
       "        const result = await kernel.invokeFunction(&#x27;_m2g_reg.del_selection&#x27;,\n",
       "                                                   [grid_id, _id], {});\n",
       "        })();\n",
       "    }\n",
       "} else {\n",
       "    function add_selection(grid_id, _id, smiles) {\n",
       "        SELECTION.multi_set(_id, smiles);\n",
       "    }\n",
       "    function del_selection(grid_id, _id) {\n",
       "        SELECTION.multi_del(_id);\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "// sort\n",
       "var sort_field = &quot;mols2grid-id&quot;;\n",
       "var sort_order = &quot;asc&quot;;\n",
       "function mols2gridSortFunction(itemA, itemB, options) {\n",
       "    var x = itemA.values()[options.valueName];\n",
       "    var y = itemB.values()[options.valueName];\n",
       "    if (typeof x === &quot;number&quot;) {\n",
       "        if (isFinite(x - y)) {\n",
       "            return x - y; \n",
       "        } else {\n",
       "            return isFinite(x) ? -1 : 1;\n",
       "        }\n",
       "    } else {\n",
       "        x = x.toLowerCase();\n",
       "        y = y.toLowerCase();\n",
       "        return (x &lt; y) ? -1: (x &gt; y) ? 1: 0;\n",
       "    }\n",
       "}\n",
       "function checkboxSort(itemA, itemB, options) {\n",
       "    if (itemA.elm !== undefined) {\n",
       "        var checkedA = itemA.elm.firstChild.checked;\n",
       "        if (itemB.elm !== undefined) {\n",
       "            var checkedB = itemB.elm.firstChild.checked;\n",
       "            if (checkedA &amp;&amp; !checkedB) {\n",
       "                return -1;\n",
       "            } else if (!checkedA &amp;&amp; checkedB) {\n",
       "                return 1;\n",
       "            } else {\n",
       "                return 0;\n",
       "            }\n",
       "        } else {\n",
       "            return -1;\n",
       "        }\n",
       "    } else if (itemB.elm !== undefined) {\n",
       "        return 1;\n",
       "    } else {\n",
       "        return 0;\n",
       "    }\n",
       "}\n",
       "$(&#x27;#mols2grid button.sort-btn&#x27;).click(function(e) {\n",
       "    var _field = $(this).attr(&quot;data-name&quot;);\n",
       "    if (_field == sort_field) {\n",
       "        $(this).removeClass(&quot;arrow-&quot; + sort_order)\n",
       "        sort_order = (sort_order === &quot;desc&quot;) ? &quot;asc&quot; : &quot;desc&quot;;\n",
       "    } else {\n",
       "        $(&#x27;#mols2grid button.sort-btn.active&#x27;).removeClass(&quot;active arrow-&quot; + sort_order);\n",
       "        sort_order = &quot;asc&quot;;\n",
       "        sort_field = _field;\n",
       "        $(this).addClass(&quot;active&quot;);\n",
       "    }\n",
       "    $(this).addClass(&quot;arrow-&quot; + sort_order)\n",
       "    if (sort_field == &quot;checkbox&quot;) {\n",
       "        listObj.sort(&quot;mols2grid-id&quot;, {order: sort_order, sortFunction: checkboxSort});\n",
       "    } else {\n",
       "        listObj.sort(_field, {order: sort_order, sortFunction: mols2gridSortFunction});\n",
       "    }\n",
       "});\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "// selection modifyers and export options\n",
       "// check all\n",
       "$(&#x27;#btn-chkbox-all&#x27;).click(function (e) {\n",
       "    var _id = [];\n",
       "    var _smiles = [];\n",
       "    listObj.items.forEach(function (item) {\n",
       "        if (item.elm) {\n",
       "            item.elm.getElementsByTagName(&quot;input&quot;)[0].checked = true;\n",
       "        } else {\n",
       "            item.show()\n",
       "            item.elm.getElementsByTagName(&quot;input&quot;)[0].checked = true;\n",
       "            item.hide()\n",
       "        }\n",
       "        _id.push(item.values()[&quot;mols2grid-id&quot;]);\n",
       "        _smiles.push(item.values()[&quot;data-SMILES&quot;]);\n",
       "    });\n",
       "    add_selection(&quot;default&quot;, _id, _smiles);\n",
       "});\n",
       "// check matching\n",
       "$(&#x27;#btn-chkbox-match&#x27;).click(function (e) {\n",
       "    var _id = [];\n",
       "    var _smiles = [];\n",
       "    listObj.matchingItems.forEach(function (item) {\n",
       "        if (item.elm) {\n",
       "            item.elm.getElementsByTagName(&quot;input&quot;)[0].checked = true;\n",
       "        } else {\n",
       "            item.show()\n",
       "            item.elm.getElementsByTagName(&quot;input&quot;)[0].checked = true;\n",
       "            item.hide()\n",
       "        }\n",
       "        _id.push(item.values()[&quot;mols2grid-id&quot;]);\n",
       "        _smiles.push(item.values()[&quot;data-SMILES&quot;]);\n",
       "    });\n",
       "    add_selection(&quot;default&quot;, _id, _smiles);\n",
       "});\n",
       "// uncheck all\n",
       "$(&#x27;#btn-chkbox-none&#x27;).click(function (e) {\n",
       "    var _id = [];\n",
       "    listObj.items.forEach(function (item) {\n",
       "        if (item.elm) {\n",
       "            item.elm.getElementsByTagName(&quot;input&quot;)[0].checked = false;\n",
       "        } else {\n",
       "            item.show()\n",
       "            item.elm.getElementsByTagName(&quot;input&quot;)[0].checked = false;\n",
       "            item.hide()\n",
       "        }\n",
       "        _id.push(item.values()[&quot;mols2grid-id&quot;]);\n",
       "    });\n",
       "    del_selection(&quot;default&quot;, _id);\n",
       "});\n",
       "// invert\n",
       "$(&#x27;#btn-chkbox-invert&#x27;).click(function (e) {\n",
       "    var _id_add = [];\n",
       "    var _id_del = [];\n",
       "    var _smiles = [];\n",
       "    listObj.items.forEach(function (item) {\n",
       "        if (item.elm) {\n",
       "            var chkbox = item.elm.getElementsByTagName(&quot;input&quot;)[0]\n",
       "            chkbox.checked = !chkbox.checked;\n",
       "        } else {\n",
       "            item.show()\n",
       "            var chkbox = item.elm.getElementsByTagName(&quot;input&quot;)[0]\n",
       "            chkbox.checked = !chkbox.checked;\n",
       "            item.hide()\n",
       "        }\n",
       "        if (chkbox.checked) {\n",
       "            _id_add.push(item.values()[&quot;mols2grid-id&quot;]);\n",
       "            _smiles.push(item.values()[&quot;data-SMILES&quot;]);\n",
       "        } else {\n",
       "            _id_del.push(item.values()[&quot;mols2grid-id&quot;]);\n",
       "        }\n",
       "    });\n",
       "    del_selection(&quot;default&quot;, _id_del);\n",
       "    add_selection(&quot;default&quot;, _id_add, _smiles);\n",
       "});\n",
       "// copy to clipboard\n",
       "$(&quot;#btn-chkbox-copy&quot;).click(function(e) {\n",
       "    navigator.clipboard.writeText(SELECTION.to_dict());\n",
       "});\n",
       "// export smiles\n",
       "$(&quot;#btn-chkbox-dlsmi&quot;).click(function(e) {\n",
       "    SELECTION.download_smi(&quot;selection.smi&quot;);\n",
       "});\n",
       "// export CSV\n",
       "$(&quot;#btn-chkbox-dlcsv&quot;).click(function(e) {\n",
       "    var sep = &quot;\\t&quot;\n",
       "    // same order as subset + tooltip\n",
       "    var columns = Array.from(listObj.items[0].elm.querySelectorAll(&quot;div.data&quot;))\n",
       "                       .map(elm =&gt; elm.classList[1]);\n",
       "    // remove &#x27;data-&#x27;\n",
       "    var header = columns.map(name =&gt; name.slice(5));\n",
       "    // csv content\n",
       "    header = [&quot;index&quot;].concat(header).join(sep);\n",
       "    var content = header + &quot;\\n&quot;;\n",
       "    for (let [index, smiles] of SELECTION.entries()) {\n",
       "        var data = listObj.items[index].values();\n",
       "        content += index;\n",
       "        columns.forEach((key) =&gt; {\n",
       "            content += sep + data[key];\n",
       "        })\n",
       "        content += &quot;\\n&quot;;\n",
       "    }\n",
       "    var a = document.createElement(&quot;a&quot;);\n",
       "    var file = new Blob([content], {type: &quot;text/csv&quot;});\n",
       "    a.href = URL.createObjectURL(file);\n",
       "    a.download = &quot;selection.csv&quot;;\n",
       "    a.click();\n",
       "    a.remove();\n",
       "});\n",
       "// update selection on checkbox click\n",
       "listObj.on(&quot;updated&quot;, function (list) {\n",
       "    $(&quot;input:checkbox&quot;).change(function() {\n",
       "        var _id = parseInt($(this).closest(&quot;.cell&quot;).attr(&quot;data-mols2grid-id&quot;));\n",
       "        if (this.checked) {\n",
       "            var _smiles = $($(this).siblings(&quot;.data-SMILES&quot;)[0]).text();\n",
       "            add_selection(&quot;default&quot;, [_id], [_smiles]);\n",
       "        } else {\n",
       "            del_selection(&quot;default&quot;, [_id]);\n",
       "        }\n",
       "    }); \n",
       "});\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "// generate images for the currently displayed molecules\n",
       "var draw_opts = {&quot;width&quot;: 160, &quot;height&quot;: 120};\n",
       "var json_draw_opts = JSON.stringify(draw_opts);\n",
       "\n",
       "var smarts_matches = {};\n",
       "\n",
       "// Load RDKit\n",
       "window\n",
       ".initRDKitModule()\n",
       ".then(function(RDKit) {\n",
       "    console.log(&#x27;RDKit version: &#x27;, RDKit.version());\n",
       "    window.RDKit = RDKit;\n",
       "    window.RDKitModule = RDKit;\n",
       "\n",
       "    // search bar\n",
       "    function SmartsSearch(query, columns) {\n",
       "    var smiles_col = columns[0];\n",
       "    smarts_matches = {};\n",
       "    var query = $(&#x27;#mols2grid #searchbar&#x27;).val();\n",
       "    var qmol = RDKit.get_qmol(query);\n",
       "    if (qmol.is_valid()) {\n",
       "        listObj.items.forEach(function (item) {\n",
       "            var smiles = item.values()[smiles_col]\n",
       "            var mol = RDKit.get_mol(smiles);\n",
       "            if (mol.is_valid()) {\n",
       "                var results = mol.get_substruct_matches(qmol);\n",
       "                if (results === &quot;\\{\\}&quot;) {\n",
       "                    item.found = false;\n",
       "                } else {\n",
       "                    item.found = true;\n",
       "                    \n",
       "                    results = JSON.parse(results);\n",
       "                    \n",
       "                    var highlights = {&quot;atoms&quot;: [], &quot;bonds&quot;: []};\n",
       "                    results.forEach(function (match) {\n",
       "                        highlights[&quot;atoms&quot;].push(...match.atoms)\n",
       "                        highlights[&quot;bonds&quot;].push(...match.bonds)\n",
       "                    });\n",
       "                    \n",
       "                    var index = item.values()[&quot;mols2grid-id&quot;];\n",
       "                    smarts_matches[index] = highlights;\n",
       "                    \n",
       "                }\n",
       "            } else {\n",
       "                item.found = false;\n",
       "            }\n",
       "            mol.delete();\n",
       "        });\n",
       "    }\n",
       "    qmol.delete();\n",
       "}\n",
       "var search_type = &quot;Text&quot;;\n",
       "$(&#x27;#mols2grid .search-btn&#x27;).click(function() {\n",
       "    search_type = $(this).text();\n",
       "    $(&#x27;#mols2grid button.search-btn.active&#x27;).removeClass(&quot;active&quot;);\n",
       "    $(this).addClass(&quot;active&quot;);\n",
       "});\n",
       "$(&#x27;#mols2grid #searchbar&#x27;).on(&quot;keyup&quot;, function(e) {\n",
       "    var query = e.target.value;\n",
       "    if (search_type === &quot;Text&quot;) {\n",
       "        smarts_matches = {};\n",
       "        listObj.search(query, [&#x27;data-index&#x27;]);\n",
       "    } else {\n",
       "        listObj.search(query, [&quot;data-SMILES&quot;], SmartsSearch);\n",
       "    }\n",
       "});\n",
       "\n",
       "    \n",
       "    // generate images for the currently displayed molecules\n",
       "RDKit.prefer_coordgen(true);\n",
       "function draw_mol(smiles, index, template_mol) {\n",
       "    var mol = RDKit.get_mol(smiles, &#x27;{&quot;removeHs&quot;: false }&#x27;);\n",
       "    var svg = &quot;&quot;;\n",
       "    if (mol.is_valid()) {\n",
       "        var highlights = smarts_matches[index];\n",
       "        if (highlights) {\n",
       "            var details = Object.assign({}, draw_opts, highlights);\n",
       "            details = JSON.stringify(details);\n",
       "            mol.generate_aligned_coords(template_mol, true);\n",
       "        } else {\n",
       "            var details = json_draw_opts;\n",
       "        }\n",
       "        svg = mol.get_svg_with_highlights(details);\n",
       "    }\n",
       "    mol.delete();\n",
       "    if (svg == &quot;&quot;) {\n",
       "        return &#x27;&lt;svg width=&quot;160&quot; height=&quot;120&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 160 120&quot;&gt;&lt;/svg&gt;&#x27;;\n",
       "    }\n",
       "    return svg;\n",
       "}\n",
       "listObj.on(&quot;updated&quot;, function (list) {\n",
       "    var query = $(&#x27;#mols2grid #searchbar&#x27;).val();\n",
       "    var template_mol;\n",
       "    if (query === &quot;&quot;) {\n",
       "        smarts_matches = {};\n",
       "        template_mol = null;\n",
       "    } else {\n",
       "        template_mol = RDKit.get_qmol(query);\n",
       "        template_mol.set_new_coords(true);\n",
       "    }\n",
       "    $(&#x27;#mols2grid .cell&#x27;).each(function() {\n",
       "        var $t = $(this);\n",
       "        var smiles = $t.children(&quot;.data-SMILES&quot;).first().text();\n",
       "        var index = parseInt(this.getAttribute(&quot;data-mols2grid-id&quot;));\n",
       "        var svg = draw_mol(smiles, index, template_mol);\n",
       "        $t.children(&quot;.data-img&quot;).html(svg);\n",
       "    });\n",
       "    if (template_mol) {\n",
       "        template_mol.delete();\n",
       "    }\n",
       "});\n",
       "    \n",
       "\n",
       "    // trigger update to activate tooltips, draw images, setup callbacks...\n",
       "    listObj.update();\n",
       "    // resize iframe to fit content\n",
       "    if (window.frameElement) {\n",
       "        window.parent.fit_height(window.frameElement);\n",
       "    }\n",
       "});\n",
       "    &lt;/script&gt;\n",
       "  &lt;/body&gt;\n",
       "&lt;/html&gt;\">\n",
       "</iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mols2grid.display(df_0.iloc[failed],mol_col=\"mol\",subset=[\"img\",\"index\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d902340",
   "metadata": {},
   "source": [
    "Now we want to delete the rows corresponding to molecules that failed the R-group decomposition from **df_O**. Since we created **df_O** from **df**, it inherited the original dataframe's index.  We'll call **reset_index** to create a new index that simply numbers the rows from 0 to len(df_0). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "9d860b21",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_0.reset_index(inplace=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "363a3257",
   "metadata": {},
   "source": [
    "Delete the failed rows from **df_0**. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "09a0980d",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_0 = df_0.drop(failed,axis=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b88a83a2",
   "metadata": {},
   "source": [
    "Get the names of the R-groups"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "37abaeb3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['R1', 'R2', 'R3', 'R4']"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r_groups = [x for x in rgd.keys() if x != \"Core\"]\n",
    "r_groups"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9729ef87",
   "metadata": {},
   "source": [
    "Add the SMILES for the R-groups to **df_0**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "54f3a74f",
   "metadata": {},
   "outputs": [],
   "source": [
    "for r in sorted(r_groups):\n",
    "    df_0[r] = rgd[r]\n",
    "    df_0[r] = df_0[r].apply(Chem.MolToSmiles)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e50a7727",
   "metadata": {},
   "source": [
    "#### View the R-groups and Their Frequency\n",
    "Create an interactive viewer for the R-groups that shows how many times each R-group was used. Use the menu below to toggle between R1, R2, R3, and R4."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "276bd085",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "77cb9052f6484f1fb83a8a4d8cfad343",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "interactive(children=(Dropdown(description='rg', options=('R1', 'R2', 'R3', 'R4'), value='R1'), Output()), _do…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "@interact(rg=r_groups)\n",
    "def display_rgroups(rg):\n",
    "    vc_df = uru.value_counts_df(df_0,rg)\n",
    "    return mols2grid.display(vc_df,smiles_col=rg,subset=[\"img\",\"count\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b63de0ff",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
